package n7.restaurant.java.Entity;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;

import n7.restaurant.java.Enum.Role;
import n7.restaurant.java.Swing.Swing;

public class Chef extends Agent {

	public static Chef grand_chef;
	private ArrayList<Plat> a_faire;
	private ArrayList<Plat> en_cours;
	private ArrayList<Plat> fini;
	private String toString;

	public String getToString() {
		return toString;
	}

	public void setToString(String toString) {
		this.toString = toString;
	}

	
	/**
	 * le methode du thread
	 * */
	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			String formule = recuCommande();
			// recu commande
			if (formule != null) {
				// commande(C4)=M0
				/*
				 * System.out.println(this); System.out.println(formule);
				 */
				int numeroMenu = Integer.parseInt(formule.substring(14, 15));
				int numeroClient = Integer.parseInt(formule.substring(10, 11));
				// System.out.println(this);
				Menu m = Menu.menus.get(numeroMenu);
				if (m != null) {
					donner_tache(m, numeroClient);
				}

			} else if (true) {
				// recu le message du pret
				// informer le serveur le plat est pret et il peut le prendre de
				// la specialiste.
				// supprimer le message
				informerServeurPlatPret();
			}
		}
	}

	@Override
	public String toString() {
		String returnString = this.getId() + ": \n";
		for (int i = 0; i < this.getEtat_mentaux().size(); i++) {
			Etat_Mental em = this.getEtat_mentaux().get(i);
			returnString += em.toString() + "\n";
		}
		return returnString;
	}

	/**
	 * informer au specialiste pour partager des taches
	 * */
	public void donner_tache(Menu m, int numeroClient) {
		// TODO Auto-generated method stub
		// informer au specialistes pour partager des tahces.
		synchronized (this) {
			for (int i = 0; i < m.getPlats().size(); i++) {
				Plat p = m.getPlats().get(i);
				/* System.out.println(p.getNom()); */
				for (int j = 0; j < this.getEtat_mentaux().size(); j++) {
					Etat_Mental e = this.getEtat_mentaux().get(j);
					// cherche
					// knowref(GC0,capacite(SP0)=entree)
					if (e.getFormule().contains(p.getType().toString())) {
						int numeroSpecialiste = Integer.parseInt(e.getFormule()
								.substring(11, 12));
						// ajouter au specialiste
						// knowref(SP0,demande(C0)=nomPlat)
						Specialiste s = Specialiste.specialistes
								.get(numeroSpecialiste);
						Etat_Mental em = new Etat_Mental();
						em.setDescription("knowref");
						em.setAgent_X(s);
						em.setFormule("demande(" + "C" + numeroClient + ")="
								+ p.getNom());
						s.addEtatMental(em);
						/* System.out.println(s); */
					}
				}
			}
			// Action:
			Swing.TAP[numeroClient] += ", informer_que(" + this.getId() + ","
					+ "_" + ",C_" + numeroClient + "commande_" + m.getId()
					+ "))";
			// supprimer
			// knowref(GC0,commande(C4)=M0);
			for (int i = 0; i < this.getEtat_mentaux().size(); i++) {
				Etat_Mental e = this.getEtat_mentaux().get(i);
				if (e.getFormule().contains("commande(C" + numeroClient + ")")
						&& e.getFormule().contains("=M")) {
					this.getEtat_mentaux().remove(i);
					break;
				}
			}
		}
	}

	public Chef() {
		super();
		this.a_faire = new ArrayList<Plat>();
		this.en_cours = new ArrayList<Plat>();
		this.fini = new ArrayList<Plat>();
	}

	public Chef(String id, Role role, ArrayList<Etat_Mental> etat_mentaux,
			Position position) {
		super(id, role, etat_mentaux, position);
		this.a_faire = new ArrayList<Plat>();
		this.en_cours = new ArrayList<Plat>();
		this.fini = new ArrayList<Plat>();
	}

	public Chef(String id, Role role, ArrayList<Etat_Mental> etat_mentaux,
			Position position, ArrayList<Plat> a_faire,
			ArrayList<Plat> en_cours, ArrayList<Plat> fini) {
		super(id, role, etat_mentaux, position);
		this.a_faire = new ArrayList<Plat>();
		this.en_cours = new ArrayList<Plat>();
		this.fini = new ArrayList<Plat>();
		this.a_faire = a_faire;
		this.en_cours = en_cours;
		this.fini = fini;
	}

	public Chef(ArrayList<Plat> a_faire, ArrayList<Plat> en_cours,
			ArrayList<Plat> fini) {
		super();
		this.a_faire = new ArrayList<Plat>();
		this.en_cours = new ArrayList<Plat>();
		this.fini = new ArrayList<Plat>();
		this.a_faire = a_faire;
		this.en_cours = en_cours;
		this.fini = fini;
	}

	public ArrayList<Plat> getA_faire() {
		return a_faire;
	}

	public void setA_faire(ArrayList<Plat> a_faire) {
		this.a_faire = a_faire;
	}

	public ArrayList<Plat> getEn_cours() {
		return en_cours;
	}

	public void setEn_cours(ArrayList<Plat> en_cours) {
		this.en_cours = en_cours;
	}

	public ArrayList<Plat> getFini() {
		return fini;
	}

	public void setFini(ArrayList<Plat> fini) {
		this.fini = fini;
	}

	public void addEtatMental(Etat_Mental e) {
		this.getEtat_mentaux().add(e);
	}

	/**
	 * Si il a recu un commande du client depuis serveur ou pas.
	 * */
	public String recuCommande() {
		synchronized (this) {
			for (int i = 0; i < this.getEtat_mentaux().size(); i++) {
				Etat_Mental em = this.getEtat_mentaux().get(i);
				// knowref(GC0,commande(C4)=M0);
				if (em.getDescription().equalsIgnoreCase("knowref")
						&& em.getFormule().contains("commande(C")) {
					return em.getFormule();
				}
			}
		}
		return null;
	}

	/**
	 * informer le serveur pour lui savoir que le plat qu'il est responsable est
	 * pret.
	 * */
	public void informerServeurPlatPret() {
		// ajouter
		// knowref(SV1, possede(C1,type)=pret)
		Etat_Mental newEM = new Etat_Mental();
		int numeroServeur = -1;
		// knowref(GC0,possede(C0,pret(type))=true)
		for (int i = 0; i < this.getEtat_mentaux().size(); i++) {
			Etat_Mental em = this.getEtat_mentaux().get(i);
			if (em.getDescription().equalsIgnoreCase("knowref")
					&& em.getFormule().contains("possede(C")
					&& em.getFormule().contains("pret(")
					&& em.getFormule().contains("true")) {
				int owner = Integer.parseInt(em.getFormule().substring(9, 10));
				// possede(C0,pret(type))=true
				String type = em.getFormule().substring(16);
				StringTokenizer st = new StringTokenizer(type, ")", true);
				type = st.nextToken();
				// informer au serveur responsable
				synchronized (this) {
					for (int j = 0; j < Serveur.serveurs.size(); j++) {
						Serveur s = Serveur.serveurs.get(j);
						for (int k = 0; k < s.getEtat_mentaux().size(); k++) {
							Etat_Mental em1 = s.getEtat_mentaux().get(k);
							// know(SV1, commande(C4,M0))
							if (em1.getFormule().contains("commande(C" + owner)) {
								// ajouter

								newEM.setAgent_X(s);
								newEM.setDescription("knowref");
								newEM.setFormule("possede(C" + owner + ","
										+ type + ")=pret");
								numeroServeur = j;
								break;
							}
						}
						if (numeroServeur != -1) {
							break;
						}
					}
					Serveur.serveurs.get(numeroServeur).addEtatMental(newEM);
					Swing.TAP[owner] += ", informer_que(" + this.getId() + ","
							+ Serveur.serveurs.get(numeroServeur).getId()
							+ ",C" + owner + "_" + type + "_pret)";
				}
				this.getEtat_mentaux().remove(i);
				break;
			}
		}
	}
}
